'use client';
import { useEffect, useMemo, type ReactNode } from 'react';
import dynamic from 'next/dynamic';
import { CheckoutPiece } from '@akinon/pz-theme/src/chrome/checkout-piece';
import { isThemeEditorDesigner } from '@akinon/pz-theme/src/chrome/checkout-pieces';
import { useAppDispatch } from '@akinon/next/redux/hooks';
import { resetCheckoutState } from '@akinon/next/redux/reducers/checkout';
import {
useFetchCheckoutQuery,
useResetCheckoutStateQuery
} from '@akinon/next/data/client/checkout';
import { useRouter, useLocalization } from '@akinon/next/hooks';
import { Button, LoaderSpinner } from '@theme/components';
import { ROUTES } from '@theme/routes';
import settings from '@theme/settings';
import {
getCheckoutVariant,
UNIFIED_VARIANTS
} from '@theme/views/checkout/variants/registry';
import { CheckoutOnePageSkeleton } from '@theme/views/checkout/variants/one-page/skeletons';
import { useResolvedCheckoutConfig } from '@theme/views/checkout/variants/use-resolved-config';
const Checkout = () => {
const { t } = useLocalization();
const router = useRouter();
const dispatch = useAppDispatch();
const { data: indexData, isLoading: isResetStateLoading } =
useResetCheckoutStateQuery(null);
const {
data: checkoutData,
isLoading: isCheckoutLoading,
isError,
refetch: refetchCheckout
} = useFetchCheckoutQuery(null, {
refetchOnMountOrArgChange: true,
skip: isResetStateLoading || !indexData
});
const { variantId, options: variantOptions } = useResolvedCheckoutConfig();
const CheckoutAuth = useMemo(
() => dynamic(() => import('@theme/views/checkout/auth')),
[]
);
const CheckoutVariant = useMemo(
() => getCheckoutVariant(variantId),
[variantId]
);
useEffect(() => {
return () => {
dispatch(resetCheckoutState());
};
}, []); // eslint-disable-line react-hooks/exhaustive-deps
// In unified mode the basket lives inside the checkout page and the basket
// page auto-redirects here while it has items — following the backend's
// basket redirect would bounce between the two pages forever. Check the
// settings.js baseline as well, since the basket page redirects based on it
// even when the async theme-settings override resolves to another variant.
const baselineVariant = (settings as { checkout?: { variant?: string } })
?.checkout?.variant;
const isUnifiedCheckout =
UNIFIED_VARIANTS.has(variantId) ||
UNIFIED_VARIANTS.has(baselineVariant ?? '');
// The designer canvas edits the checkout page itself — an empty test basket
// must never navigate the iframe to the basket page, or the composition
// being authored disappears mid-edit. Live keeps the redirect untouched.
if (
!isUnifiedCheckout &&
checkoutData?.redirect_url?.includes('basket') &&
!isThemeEditorDesigner()
) {
router.push(ROUTES.BASKET);
return null;
}
// One stable CheckoutPiece instance hosts every gate below: the latch runs
// once, and the loading-to-variant transition is a child swap under the same
// (possibly portaled) position — no remounts mid-session.
let body: ReactNode;
if (checkoutData?.template_name === 'orders/index.html') {
body = (